home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-07-15 | 28.3 KB | 749 lines | [TEXT/MPS ] |
- *
- * Apple Macintosh Developer Technical Support
- *
- * CLUTSample
- *
- * CLUTSampleMisc.a - Assembler Source
- *
- *
- * Loosely based in the sample SAMPLE this program shows
- * how to create a window and display on it the colors of the CLUT
- * associated with the device the window sits on top of.
- *
- * Left to the curious reader are some improvements such as, remembering the
- * positions of each open window, so if you use this program to monitor your
- * color tables it will position the windows in the last place you opened them.
- * The treatment of direct devices is kind of 'casual' a better color display may
- * be appropriate. Last, it may be desireable to change the size of the color
- * rectangles depending on the depth of the color table.
-
- * Check Sample sources for more detailed documentation.
-
- * Copyright © 1990 Apple Computer, Inc.
- * All rights reserved.
-
-
- * ================================================
- * -------------- INCLUDES SECTION ----------------
- * ================================================
-
- PRINT PUSH,OFF ; don't print any of this stuff
-
- INCLUDE 'ToolEqu.a'
- INCLUDE 'Traps.a'
- INCLUDE 'PackMacs.a'
- INCLUDE 'QuickEqu.a'
- INCLUDE 'SysEqu.a'
- INCLUDE 'CLUTSample.inc1.a' ; all our macros and data templates
-
- PRINT POP ; restore the PRINT options
-
-
- * ================================================
- * ----------- DATA STORAGE USAGE ---------------
- * ================================================
- IMPORT QD:QDGlobals
- IMPORT G:AppGlobals
-
-
- * ================================================
- * FUNCTION TrapAvailable(tNumber: INTEGER): BOOLEAN;
- * ================================================
- SEG 'Initialize' ; case sensitive
- TrapAvailable FUNC EXPORT ; any source file can use this routine
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- Result DS.W 1 ; function's result returned to caller
- ParamBegin EQU * ; start parameters after this point
- tNumber DS.W 1 ; the trap number passed by caller
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- TrapAddress DS.L 1 ; local copy of trap address
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- MOVE.W #False,Result(A6) ; initialize function's result
-
- MOVE.W tNumber(A6),D0 ; get trap word into D0
- BTST #ToolTrapBit,D0 ; test if number is Tool trap
- BEQ.S GetOSTrap ; off means a new OS trap number
-
- MOVE.W G.Mac.machineType,D1 ; get the machine type we're running
- CMPI.W #envMachUnknown,D1 ; are we on a future machine?
- BEQ.S GetToolTrap ; yes, go ahead and test for a new Tool trap
-
- CMPI.W #envMacII,D1 ; are we on a Mac II or better?
- BGE.S GetToolTrap ; yes, go ahead and test for a new Tool trap
-
- * ------------- TEST FOR EXCEEDING TRAP TABLE -------------
- * At this point we know we're on a Mac 512E, Plus, or SE and need to
- * test the trap number for being in the range of < $0200
-
- AND.W #$03FF,D0 ; mask off the ToolTrap bits
- CMPI.W #$01FF,D0 ; is this trap in our trap table?
- BLE.S GetToolTrap ; yes, go ahead and test for a new Tool trap
- BRA.S Exit ; no, then this trap cannot be present
-
- * ------------- TEST FOR NEW TOOL TRAP -------------
-
- GetToolTrap _GetTrapAddress ,NewTool ; NewTool trap macro, trap is in D0
- MOVE.L A0,TrapAddress(A6) ; save a copy of the trap address
- BRA.S TestUnimp ; test against Unimplemented trap
-
- * ------------- TEST FOR NEW OS TRAP -------------
-
- GetOSTrap _GetTrapAddress ,NewOS ; NewOS trap macro, trap is in D0
- MOVE.L A0,TrapAddress(A6) ; save a copy of the trap address
- TestUnimp MOVE.W #Unimplemented,D0 ; get address of Unimplemented trap
- _GetTrapAddress
- CMPA.L TrapAddress(A6),A0 ; see if trap is implemented
- BEQ.S Exit ; nope, they're the same
- MOVE.W #True,Result(A6) ; yes, we've got the trap
-
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo TrapAval ; this name will appear in the debugger
- ENDF
-
- * ================================================
- * FUNCTION GoGetRect(rectID: INTEGER; VAR theRect: Rect) : BOOLEAN;
- * ================================================
- * This utility loads the global rectangles that are used by the window
- * drawing routines. It shows how the resource manager can be used to hold
- * values in a convenient manner. These values are then easily altered without
- * having to re-compile the source code. GoGetRect will return a BOOLEAN that
- * indicates if it was successful in getting the rectangle.
-
- * A0 is being used for resource handle.
-
- SEG 'Initialize' ; case sensitive
- GoGetRect FUNC EXPORT ; any source file can use this routine
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- Result DS.W 1 ; function's result returned to caller
- ParamBegin EQU * ; start parameters after this point
- RectID DS.W 1 ; resource ID of rect passed by caller
- TheRect DS.L 1 ; the rect's pointer passed by caller
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- MOVE.W #False,Result(A6) ; initialize function's result
-
- CLR.L -(SP) ; create space for result
- MOVE.L #'RECT',-(SP)
- MOVE.W RectID(A6),-(SP) ; get the stop light's rect
- _GetResource
- MOVEA.L (SP)+,A0 ; handle to RECT resource in A0
- CMPA.L #NIL,A0 ; test for NIL handle
- BEQ.S Exit ; didn't get resource, exit this procedure
-
-
- * -------- COPY THE RESOURCE TO THE RECT --------
-
- MOVE.W #True,Result(A6) ; we got the resource, return true
- MOVEA.L (A0),A0 ; pointer to RECT resource in A0
- MOVEA.L TheRect(A6),A1 ; pointer to the dest. RECT in A1
- MOVE.L topLeft(A0),topLeft(A1) ; copy to the rect passed to us
- MOVE.L botRight(A0),botRight(A1)
-
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo GetRect ; this name will appear in the debugger
- ENDF
-
- * ================================================
- * FUNCTION IsDAWindow(window: WindowPtr): BOOLEAN;
- * ================================================
- * Check if a window belongs to a desk accessory. DA window has a negitive kind.
-
- SEG 'Main'
- IsDAWindow FUNC EXPORT ; any source file can use this routine
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- Result DS.W 1 ; function's result returned to caller
- ParamBegin EQU * ; start parameters after this point
- TheWindow DS.L 1 ; a window's pointer passed by caller
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- MOVE.W #False,Result(A6) ; first, initialize the result
- CMPI.L #NIL,TheWindow(A6) ; valid pointer?
- BEQ.S Exit ; it was NIL, look out!
-
- MOVEA.L TheWindow(A6),A0 ; get the window pointer
- MOVE.W WindowKind(A0),D0 ; what kind of window was it?
- BPL.S Exit ; DA windows are negitive
-
- MOVE.W #True,Result(A6) ; return true to the caller
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo IsDAWind ; this name will appear in the debugger
- ENDF
-
- * ================================================
- * FUNCTION IsAppWindow(window: WindowPtr): BOOLEAN;
- * ================================================
- * Check to see if a window belongs to the application. If the window pointer
- * passed was NIL, then it could not be an application window. WindowKinds
- * that are negative belong to the system and windowKinds less than userKind
- * are reserved by Apple except for windowKinds equal to dialogKind, which
- * means it is a dialog.
- * In order to reduce the chance of accidentally treating some window
- * as an AppWindow that shouldn't be, we'll only return true if the windowkind
- * is userKind. If you add different kinds of windows to Sample you'll need
- * to change how this all works.
-
- SEG 'Main'
- IsAppWindow FUNC EXPORT ; any source file can use this routine
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- Result DS.W 1 ; function's result returned to caller
- ParamBegin EQU * ; start parameters after this point
- TheWindow DS.L 1 ; a window's pointer passed by caller
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- MOVE.W #False,Result(A6) ; first, initialize the result
- CMPI.L #NIL,TheWindow(A6) ; valid pointer?
- BEQ.S Exit ; it was NIL, look out!
-
- MOVEA.L TheWindow(A6),A0 ; get the window pointer
- MOVE.W WindowKind(A0),D0 ; what kind of window was it?
- CMPI.W #UserKind,D0 ; was it an application window?
- BNE.S Exit ; no, result is going to be false
-
- MOVE.W #True,Result(A6) ; return true to the caller
-
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo IsAppWin ; this name will appear in the debugger
- ENDF
-
- * ================================================
- * PROCEDURE AlertUser;
- * ================================================
- * Display an alert that tells the user an error occurred, then exit the program.
- * This routine is used as an ultimate bail-out for serious errors that prohibit
- * the continuation of the application. Errors that do not require the termination
- * of the application should be handled in a different manner. Error checking and
- * reporting has a place even in the simplest application. For simplicity, the alert
- * displayed here only says that an error occurred, but not what it was. There are
- * various methods available for being more specific.
-
- SEG 'Main' ; case sensitive
- AlertUser PROC EXPORT ; any source file can use this routine
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start parameters after this point
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- CLR.W -(SP) ; space for result of Alert
- MOVE.W #rUserAlert,-(SP) ; resource for alert dialog
- CLR.L -(SP) ; no filter procedure used here
- _Alert ; read the resource and display it
- MOVE.W (SP)+,D0 ; I don't care which item is was
- _ExitToShell ; we're out of here, no error recovery
-
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo AlrtUser ; this name will appear in the debugger
- ENDP
-
- * ================================================
- * FUNCTION DoCloseWindow(window: WindowPtr) : BOOLEAN;
- * ================================================
- * At this point, if there was a document associated with a window, you could
- * do any document saving processing if it is 'dirty'. DoCloseWindow would
- * return TRUE if the window actually closes, i.e., the user does not cancel
- * from a save dialog. This result is handy when the user quits an application,
- * but then cancels a save of a document associated with a window. We also added
- * code to close the application window since otherwise, the termination routines
- * would never stop looping, waiting for FrontWindow to return NIL.
-
- SEG 'Main' ; case sensitive
- DoCloseWindow FUNC EXPORT ; any source file can use this routine
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- Result DS.W 1 ; function's result returned to caller
- ParamBegin EQU * ; start parameters after this point
- WindowPtr DS.L 1 ; passed window pointer parameter
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- MOVE.W #True,Result(A6); ; initialize the function's result
-
- CLR.W -(SP) ; space for result of IsDAWindow
- MOVE.L WindowPtr(A6),-(SP) ; pass the window pointer
- BSR IsDAWindow
- MOVE.W (SP)+,D0 ; result of IsDAWindow
- CMPI.W #True,D0
- BNE.S @1 ; this wasn't a DA window
-
- MOVEA.L WindowPtr(A6),A0 ; get window pointer
- MOVE.W WindowKind(A0),-(SP) ; pass the refNum of DA
- _CloseDeskAcc
- BRA.S Exit ; all done
-
- @1 CLR.W -(SP) ; space for result of IsAppWindow
- MOVE.L WindowPtr(A6),-(SP) ; pass a the window pointer
- BSR IsAppWindow
- MOVE.W (SP)+,D0 ; result of IsAppWindow
- CMPI.W #True,D0
- BNE.S Exit ; it wasn't our application's window
-
- MOVE.L WindowPtr(A6),-(SP) ; close window, it shouldn't be a dialog
- _CloseWindow ; close the application window
-
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo ClosWind ; this name will appear in the debugger
- ENDF
-
- * ================================================
- * PROCEDURE Terminate;
- * ================================================
- * Clean up the application and exit. We close all of the windows so that
- * they can update their documents, if any. We don't have much to do here.
- * Just close our windows and then exit. If we find out that a Cancel has
- * occurred (DoCloseWindow will return False) we won't exit to the shell,
- * but will simply exit this procedure.
-
- SEG 'Main' ; case sensitive
- Terminate PROC EXPORT
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start parameters after this point
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- WindowPtr DS.L 1 ; local variable for a window pointer
- Closed DS.W 1 ; local variable for looping
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- IMPORT DoCloseWindow
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- MOVE.W #True,Closed(A6) ; initialize local variable
-
- Loop CLR.L -(SP) ; space for front window pointer
- _FrontWindow
- MOVE.L (SP)+,WindowPtr(A6) ; get the front window pointer
- CMPI.L #NIL,WindowPtr(A6) ; is there a front window?
- BEQ.S @1 ; there are no more windows
-
- CLR.W -(SP) ; space for result of DoCloseWindow
- MOVE.L WindowPtr(A6),-(SP) ; pass the window pointer
- BSR DoCloseWindow ; close all our windows
- MOVE.W (SP)+,Closed(A6) ; get result of DoCloseWindow
- CMPI.W #True,Closed(A6) ; what's the result of DoCloseWindow?
- BNE.S Exit ; user didn't want to close that window
-
- BRA.S Loop ; loop again and close the next window
-
- @1 CMPI.W #True,Closed(A6) ; should we really terminate?
- BNE.S Exit ; no, exit this procedure
-
- _ExitToShell ; we're done, let's get out of here
-
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo Terminat ; this name will appear in the debugger
- ENDP
-
- * ================================================
- * PROCEDURE AdjustMenus;
- * ================================================
- * Enable and disable menus based on the current state. The user can only select
- * enabled menu items. We set up all the menu items before calling MenuSelect or
- * MenuKey, since these are the only times that a menu item can be selected. Note
- * that MenuSelect is also the only time the user will see menu items. This
- * approach to deciding what enable/disable state a menu item has the advantage
- * of concentrating all the decision making in one routine, as opposed to being
- * spread throughout the application. Other application designs may take a
- * different approach that are just as valid.
-
- SEG 'Main' ; case sensitive
- AdjustMenus PROC EXPORT ; any source file can use this routine
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start parameters after this point
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- FrontMost DS.L 1 ; local copy of the front window
- Menu DS.L 1 ; local copy of the menu handle
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- CLR.L -(SP) ; space for result
- _FrontWindow
- MOVE.L (SP)+,FrontMost(A6) ; save the front window
-
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo AdjstMnu ; this name will appear in the debugger
- ENDP
-
- * ================================================
- * PROCEDURE GetGlobalMouse(VAR mouse: Point);
- * ================================================
- * Get the global coordinates of the mouse. When you call OSEventAvail
- * it will return either a pending event or a null event. In either case,
- * the where field of the event record will contain the current position
- * of the mouse in global coordinates and the modifiers field will reflect
- * the current state of the modifiers. Another way to get the global
- * coordinates is to call GetMouse and LocalToGlobal, but that requires
- * being sure that thePort is set to a valid port.}
-
- SEG 'Main' ; case sensitive
- GetGlobalMouse PROC EXPORT ; any source file can use this routine
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start parameters after this point
- Mouse DS.L 1 ; passed reference to mouse position
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- TheEvent DS EventRecord ; local copy of the event record
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- MOVE.W #NoEvents,D0 ; we aren't interested in any events
- LEA TheEvent(A6),A0 ; point to event record
- _OSEventAvail ; just the mouse position
- MOVE.L Mouse(A6),A0 ; deref address of mouse
- MOVE.L TheEvent.Where(A6),(A0) ; stuff new value
-
- UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo GetGlobalMouse ; this name will appear in the debugger
- ENDP
-
- * ================================================
- * PROCEDURE DrawClut(window: WindowPtr);
- * ================================================
- *
- * This procedure finds the max depth device for the window port and uses that
- * device to draw the colors in the window.
-
- SEG 'Main' ; case sensitive
- DrawClut PROC EXPORT ; any source file can use this routine
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start parameters after this point
- WindowPtr DS.L 1 ; passed parameter of the window pointer
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- Color DS.W 3
- OldGDev DS.l 1 ; save current GDevice
- wRectBR DS.L 1 ;
- wRectTL DS.L 1 ; local storage for rect
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- WITH StackFrame,ClutWData ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- MOVE.L WindowPtr(A6),-(SP)
- _SetPort ; set the current port to use
-
- MOVE.L theGDevice,OldGDev(a6) ; save current device
-
- ; Now we want to check the max device the window is on in order to use its color table
- ; to display colors.
-
- move.l WindowPtr(a6), A0 ; get pointer to port
- ADD.L #$10,A0 ; point to rectangle
- LEA wRectTL(a6),a1
- MOVE.L (a0)+,(a1)+ ; copy topleft
- MOVE.L (a0)+,(a1)+ ; copy bottomright
- PEA wRectTL(a6) ; push rect
- _LocalToGlobal ; globalize topleft
- PEA wRectBR(a6) ; push rect
- _LocalToGlobal ; globalize bottomright
-
- clr.l -(sp) ; make room for result
- PEA wRectTL(a6) ; push rect
- _GetMaxDevice ; don't touch result
-
- CMP.L #0,(sp) ; check result
- BEQ @1 ; if nil use current device
-
- _SetGDevice ; the max dev is in the stack
-
- @1 Move.L #255,D3
- Move.w #4,-(SP)
- Move.w #4,-(SP)
- _PenSize
- ClutLoop:
- Move.L D3,-(SP)
- Pea Color(A6)
- _Index2Color
- Pea Color(A6)
- _RGBForeColor
- ; Build 16*16 array = 256 colors
- Move.w D3,D0 ; Current color index
- And.w #$000F,D0 ; mod 16 (16 colors per row)
- ASL.w #2,D0 ; times 4 (pen width)
- Move.w D0,-(SP) ; set ‘left’ for MoveTo
- Move.w D3,D0 ; Current index
- LSR.w #4,D0 ; divided by 16 (and lose low order bits)
- ASL.w #2,D0 ; times 4 (pen width)
- Move.w D0,-(SP) ; set ‘top’ for MoveTo
- _MoveTo
- Clr.l -(SP)
- _Line ; Line length of zero ‘stamps’ in pen
- DBRA D3,ClutLoop
-
- Exit MOVE.L OldGDev(a6),theGDevice ; restore current device
-
- UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo DrawClut
- ENDP
-
- * ================================================
- * PROCEDURE NulMouse(window: WindowPtr; event: EventRecord);
- * ================================================
- SEG 'Main' ; case sensitive
- NulMouse PROC EXPORT
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start parameters after this point
- WindowPtr DS.L 1 ; passed parameter of the window pointer
- EventPtr DS.L 1 ; pointer to the event record
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- * insert locals here
- LocalSize EQU * ; size of all the local variables
- ENDR
- ; IMPORT
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
-
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo NulMouse
- ENDP
-
- * ================================================
- * PROCEDURE AdjustCursor(mouse: Point; region: RgnHandle);
- * ================================================
- * Change the cursor's shape, depending on its position. This also calculates the
- * region where the current cursor resides (for WaitNextEvent). If the mouse is
- * ever outside of that region, an event would be generated, causing this routine
- * to be called, allowing us to change the region to the region the mouse is
- * currently in. If there is more to the event than just the mouse moved, we
- * get called before the event is processed to make sure the cursor is the right
- * one. In any (ahem) event, this is called again before we fall back into WNE.
- * 1.02 - Removed the mouse position parameter and instead use the current position
- * of the mouse by calling GetMouse and LocalToGlobal.
-
- SEG 'Main' ; case sensitive
- AdjustCursor PROC EXPORT
-
- StackFrame RECORD {A6Link},DECR ; build a stack frame record
- ParamBegin EQU * ; start parameters after this point
- Where DS.L 1 ; the mouse location passed to us
- MouseRegion DS.L 1 ; passed pointer to current region
- ParamSize EQU ParamBegin-* ; size of all the passed parameters
- RetAddr DS.L 1 ; place holder for return address
- A6Link DS.L 1 ; place holder for A6 link
- FrontMost DS.L 1 ; local pointer to the front window
- ArrowRgn DS.L 1 ; local handle to the arrow cursor region
- PlusRgn DS.L 1 ; local handle to the plus cursor region
- LocalSize EQU * ; size of all the local variables
- ENDR
-
- IMPORT IsDAWindow,IsAppWindow
-
- WITH StackFrame ; cover our local stack frame
- LINK A6,#LocalSize ; allocate our local stack frame
-
- CLR.W -(SP) ; space for result of IsAppWindow
- CLR.L -(SP) ; space for result of FrontWindow
- _FrontWindow ; push front window pointer
- MOVE.L (SP),FrontMost(A6) ; copy pointer and keep it on stack
- BSR IsDAWindow ; is this an application window?
- MOVE.W (SP)+,D0
- CMPI.W #True,D0
- BEQ.W Exit ; not our window, don't adjust the cursor
- CMPI.W #True,G.InBackground
- BEQ.W Exit ; and do nothing if we're in the background
-
- * ------------- INITIALIZE SOME REGION DATA -------------
-
- CLR.L -(SP)
- _NewRgn ; create an empty plus region
- MOVE.L (SP)+,PlusRgn(A6)
- CLR.L -(SP)
- _NewRgn ; create an empty arrow region
- MOVE.L (SP)+,ArrowRgn(A6)
- MOVE.L ArrowRgn(A6),-(SP) ; arrow region handle
- MOVE.W #ExtremeNeg,-(SP) ; big left corner
- MOVE.W #ExtremeNeg,-(SP) ; big top corner
- MOVE.W #ExtremePos,-(SP) ; big right corner
- MOVE.W #ExtremePos,-(SP) ; big bottom corner
- _SetRecRgn ; really big rectangular region
-
- CLR.W -(SP)
- MOVE.L FrontMost(A6),-(SP)
- BSR IsAppWindow ; is this an application window?
- MOVE.W (SP)+,D0
- CMPI.W #True,D0
- BNE.S @1 ; our window isn't in front?
-
- * ------------- CALCULATE THE PLUS REGION -------------
-
- MOVE.L FrontMost(A6),-(SP)
- _SetPort ; set the current port to us
- MOVEA.L FrontMost(A6),A0
- MOVE.W portBits+bounds+left(A0),D0
- NEG.W D0 ; offset window's left edge...
- MOVE.W D0,-(SP) ; to the screen's left edge
- MOVEA.L FrontMost(A6),A0
- MOVE.W portBits+bounds+top(A0),D0
- NEG.W D0 ; offset window's top edge...
- MOVE.W D0,-(SP) ; to the screen's top edge
- _SetOrigin ; make window rect global
- MOVE.L PlusRgn(A6),-(SP) ; handle to empty plus region
- MOVEA.L FrontMost(A6),A0 ; pointer to our window
- PEA portRect(A0) ; window rect's global coordinates
- _RectRgn ; make global window rect into region
- MOVE.L PlusRgn(A6),-(SP) ; get intersection of plus and window region
- MOVEA.L FrontMost(A6),A0
- MOVE.L visRgn(A0),-(SP) ; get front window's visRgn
- MOVE.L PlusRgn(A6),-(SP) ; resulting region will be in PlusRgn
- _SectRgn ; intersection the two regions
- CLR.L -(SP) ; reset the origin of our window to 0,0
- _SetOrigin
-
- @1 MOVE.L ArrowRgn(A6),-(SP) ; the really big rectangular region
- MOVE.L PlusRgn(A6),-(SP) ; the region of our window
- MOVE.L ArrowRgn(A6),-(SP) ; intersetion of the Arrow and Plus region
- _DiffRgn ; this is the region where the Arrow shows
- CLR.W -(SP) ; space for result of PtInRect
- MOVE.L Where(A6),-(SP) ; here's the mouse
- MOVE.L PlusRgn(A6),-(SP) ; where the arrow should show up
- _PtInRgn ; was cursor in the arrow region?
- MOVE.W (SP)+,D0
- CMPI.W #True,D0
- BNE.S @2 ; cursor was in arrow region
-
- * ------------- SET THE CURSOR AND NEW MOUSE REGION -------------
-
- CLR.L -(SP) ; space for result
- MOVE.W #plusCursor,-(SP) ; I want the plus cursor now!
- _GetCursor
- MOVEA.L (SP)+,A0 ; get the handle
- CMPA.L #NIL,A0
- BEQ.S Exit ; check for NIL like a good boy
- MOVE.L (A0),-(SP) ; got the plus cursor
- _SetCursor ; set cursor to plus
- MOVE.L PlusRgn(A6),-(SP) ; current region containing cursor
- MOVE.L MouseRegion(A6),-(SP) ; set it to the new region
- _CopyRgn
- BRA.S @3 ; we're done, get out of here
-
- @2 PEA QD.Arrow ; got arrow cursor at InitGraf
- _SetCursor ; set cursor to the Arrow
- MOVE.L ArrowRgn(A6),-(SP) ; current region containing cursor
- MOVE.L MouseRegion(A6),-(SP) ; set it to the new region
- _CopyRgn
-
- @3 MOVE.L PlusRgn(A6),-(SP) ; dispose of our two temporary regions
- _DisposRgn
- MOVE.L ArrowRgn(A6),-(SP)
- _DisposRgn
-
- Exit UNLK A6 ; destroy the link
- MOVEA.L (SP)+,A0 ; pull off the return address
- ADDA.L #ParamSize,SP ; strip all of the caller's parameters
- JMP (A0) ; return to the caller
-
- DbgInfo AdjstCur ; this name will appear in the debugger
- ENDP
-
- END ; end of this source file
-